From 3d1b950e85b9d668d830bca68f5ab154a6f06aee Mon Sep 17 00:00:00 2001 From: Phlosioneer Date: Sun, 1 Apr 2018 06:08:40 -0400 Subject: [PATCH] Implement size_hint for some iterators This PR implements size_hints for Deps, DepsNotReplaced, and Members. These size_hints are used extensively by cargo to allocate Vecs. Deps, DepsNotReplaced, and RcVecIter also now implement ExactSizeIterator. --- src/cargo/core/resolver/resolve.rs | 22 ++++++++++++++++++++++ src/cargo/core/workspace.rs | 5 +++++ 2 files changed, 27 insertions(+) diff --git a/src/cargo/core/resolver/resolve.rs b/src/cargo/core/resolver/resolve.rs index 08805eba2..73d30b159 100644 --- a/src/cargo/core/resolver/resolve.rs +++ b/src/cargo/core/resolver/resolve.rs @@ -203,8 +203,19 @@ impl<'a> Iterator for Deps<'a> { .and_then(|e| e.next()) .map(|id| self.resolve.replacement(id).unwrap_or(id)) } + + fn size_hint(&self) -> (usize, Option) { + match self.edges { + // Note: Edges is actually a std::collections::hash_set::Iter, which + // is an ExactSizeIterator. + Some(ref iter) => iter.size_hint(), + None => (0, Some(0)) + } + } } +impl<'a> ExactSizeIterator for Deps<'a> {} + pub struct DepsNotReplaced<'a> { edges: Option>, } @@ -215,4 +226,15 @@ impl<'a> Iterator for DepsNotReplaced<'a> { fn next(&mut self) -> Option<&'a PackageId> { self.edges.as_mut().and_then(|e| e.next()) } + + fn size_hint(&self) -> (usize, Option) { + match self.edges { + // Note: Edges is actually a std::collections::hash_set::Iter, which + // is an ExactSizeIterator. + Some(ref iter) => iter.size_hint(), + None => (0, Some(0)) + } + } } + +impl<'a> ExactSizeIterator for DepsNotReplaced<'a> {} diff --git a/src/cargo/core/workspace.rs b/src/cargo/core/workspace.rs index 9377b185c..0c20f63e6 100644 --- a/src/cargo/core/workspace.rs +++ b/src/cargo/core/workspace.rs @@ -776,6 +776,11 @@ impl<'a, 'cfg> Iterator for Members<'a, 'cfg> { } } } + + fn size_hint(&self) -> (usize, Option) { + let (_, upper) = self.iter.size_hint(); + (0, upper) + } } impl MaybePackage { -- 2.30.2